/**
 * @author Federico Consoli
 *
 * Released under GNU GPLv3 (http://www.gnu.org/licenses/gpl-3.0.txt)
 */


#include "Service_1.h"

using namespace std;
using namespace Magick;

Service_1::Service_1(string nuovo_ip, unsigned short nuovo_porta_base, string name_of_service) {
    name = name_of_service;
    cout << display() + "Building service 1... ";
    srand((unsigned) time(0));
    ip = nuovo_ip;
    porta_base = nuovo_porta_base;
    name = name_of_service;
    cout << "Done\n";
}

Service_1::~Service_1() {
    cout << display() + "Services 1 closed\n";
}

void Service_1::menu(Server* registro_locale) {
    registro_locale->name = name;
    int quit = 0;
    int all = 0;
    int scelta;
    int num_serv;
    while (!quit) {
        cout << "\n--------------- [SERVICE 1 - MENU] ---------------" << endl;
        cout << "0 - Exit\n";
        cout << "1 - Register Service" << endl;
        cout << "2 - Unregister service" << endl;
        cout << "3 - Lists the services available" << endl;        
        cout << "--------------- [SERVICE 1 - MENU] ---------------" << endl;
        cout << "> ";
        cin >> scelta;
        
        switch (scelta) {
            case 0:
                registro_locale->deregistrati();
                quit = 1;
                break;
            case 1:
                cout << "\n-> Enter the number of the service function to record\n";
                cout << "-> Press 0 to register all services\n> ";
                cin >> num_serv;
                if (num_serv == 0) {
                    all = 1;
                    num_serv = 1;
                }
                switch (num_serv) {
                    case 1:
                        registro_locale->registra_servizio("Rotate image", "int buffer", "buffer", ip, porta_base + 1);
                        num_serv = 2;
                        if (!all) break;
                    case 2:
                        registro_locale->registra_servizio("Horizontal Flip image", "buffer", "buffer", ip, porta_base + 5);
                        break;
                    default:
                        cout << "Unrecognized function number\n";
                        break;
                }
                break;
            case 2:
                 cout << "-> Enter the number of the service function to unregister\n";
                cout << "-> Press 0 to unregister all services\n";
                cin >> num_serv;
               
                if (num_serv == 0)
                    registro_locale->deregistrati();
                else if (num_serv == 1)
                    registro_locale->deregistra_servizio("Rotate image", ip, porta_base + 1);
                else if (num_serv == 2)
                    registro_locale->deregistra_servizio("Horizontal Flip image", ip, porta_base + 5);
                else
                    cout << "Unrecognized function number\n";
                break;
            case 3:
                cout << "\nServices available are:\n";
                cout << "1. Rotate image, on ip " << ip << " and port " << porta_base + 1 << endl;
                cout << "2. Horizontal Flip image, on ip " << ip << " and port " << porta_base + 5 << endl;
                break;
            
            default:
                cout << "Unrecognized command number\n";
                break;
        }
    }
}

void Service_1::rotate(Response *R, int sd) {
    cout << display() + "Rotate image started\n";
    string temp_file_in;
    string temp_file_out;
    int crop_enable;
    Connection::recv_int(crop_enable, sd);
    Response::valori*val_in = R->ricevi_pacchetto(sd, "in");
    Connection::random_string(temp_file_in);
    temp_file_in.append(".jpg");
    //Salvo il buffer in un file con un nome temporaneo
    Connection::string_to_file(val_in->buffer[0], temp_file_in, val_in->bufflen[0]);
    //Lo apro
    Image image;
    image.quality(100);
    image.read(temp_file_in.c_str());
    if ((image.columns() > MAX_CROP_SIZE || image.rows() > MAX_CROP_SIZE) && crop_enable) {
        size_t centrox = image.columns() / 2;
        size_t centroy = image.rows() / 2;
        size_t x = centrox - MAX_IMG_SIZE / 2;
        size_t y = centroy - MAX_IMG_SIZE / 2;
        image.crop(Geometry(MAX_IMG_SIZE, MAX_IMG_SIZE, x, y));
    }
    if (image.columns() > MAX_IMG_SIZE || image.rows() > MAX_IMG_SIZE)
        image.trim();
    image.rotate(val_in->array[0]);
    Connection::random_string(temp_file_out);
    temp_file_out.append(".jpg");
    image.write(temp_file_out.c_str());
    Response::valori*pacchetto_uscita = R->pacchetto_vuoto("out");
    Connection::file_to_string(pacchetto_uscita->buffer[0], temp_file_out, pacchetto_uscita->bufflen[0]);
    R->invia_pacchetto(pacchetto_uscita, sd, "out");
    Connection::remove_file(temp_file_out);
    Connection::remove_file(temp_file_in);
    R->rem_val(val_in, "in");
    R->rem_val(pacchetto_uscita, "out");
    cout << display() + "Rotate image end\n";
}

void Service_1::mirror(Response *R, int sd) {
    cout << display() + "Horizontal Flip image started\n";
    string temp_file_in;
    string temp_file_out;
    Response::valori*val_in = R->ricevi_pacchetto(sd, "in");
    Connection::random_string(temp_file_in);
    temp_file_in.append(".jpg");
    //Salvo il buffer in un file con un nome temporaneo
    Connection::string_to_file(val_in->buffer[0], temp_file_in, val_in->bufflen[0]);
    //Lo apro
    Image image;
    image.quality(100);
    image.read(temp_file_in.c_str());
    image.flip();
    //Salvo l'output su un file temporaneo    
    Connection::random_string(temp_file_out);
    temp_file_out.append(".jpg");
    image.write(temp_file_out.c_str());
    Response::valori*pacchetto_uscita = R->pacchetto_vuoto("out");
    Connection::file_to_string(pacchetto_uscita->buffer[0], temp_file_out, pacchetto_uscita->bufflen[0]);
    R->invia_pacchetto(pacchetto_uscita, sd, "out");
    Connection::remove_file(temp_file_out);
    Connection::remove_file(temp_file_in);
    R->rem_val(val_in, "in");
    R->rem_val(pacchetto_uscita, "out");
    cout << display() + "Horizontal Flip image end\n";
}

